package hde;

import static org.junit.Assert.assertTrue;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;
import robocode.control.testing.RobotTestBed;

/**
 * Test to see if gun is pointing at correct target.
 * 
 * @author Derek Hirano
 */

public class TestLtrboomTargeting extends RobotTestBed {
  
  /** True if gun is targeting target robot. */ 
  boolean gunOnTarget = false;
  
  /**
   * Specifies that SittingDuck and Ltrboom are to be matched up in this test case.
   * @return The comma-delimited list of robots in this match.
   */
  @Override
  public String getRobotNames() {
    return "sample.SittingDuck,hde.Ltrboom";
  }
  
  /**
   * This test runs for 10 round.
   *
   * @return The number of rounds.
   */
  @Override
  public int getNumRounds() {
    return 10;
  }
  
  /**
   * After each turn, check to see if gun is pointing at target.
   *
   * @param event Info about the current state of the battle.
   */
  @Override
  public void onTurnEnded(TurnEndedEvent event) {
 
    IRobotSnapshot robot = event.getTurnSnapshot().getRobots()[1];
    IRobotSnapshot target = event.getTurnSnapshot().getRobots()[0];
    
    double robotX = robot.getX();
    double robotY = robot.getY();
    double targetX = target.getX();
    double targetY = target.getY();
    
    if (targetX > robotX) {
      if (targetY > robotY) {
        if (((Math.toDegrees(Math.asin((targetX - robotX) / 
            Math.hypot((targetX - robotX), (targetY - robotY))))) - 5) < robot.getGunHeading()
            && 
            ((Math.toDegrees(Math.asin((targetX - robotX) / 
                Math.hypot((targetX - robotX), (targetY - robotY))))) + 5) 
                > robot.getGunHeading()) {
          gunOnTarget = true;
        }
      }
      else {
        if ((180 - (Math.toDegrees(Math.asin((targetX - robotX) / 
            Math.hypot((targetX - robotX), (robotY - targetY))))) - 5) < robot.getGunHeading()
            && 
            (180 - (Math.toDegrees(Math.asin((targetX - robotX) / 
                Math.hypot((targetX - robotX), (robotY - targetY))))) + 5) 
                > robot.getGunHeading()) {
          gunOnTarget = true;
        }
      }
    }
    else {
      if (targetY > robotY) {
        if ((180 + (Math.toDegrees(Math.asin((robotX - targetX) / 
            Math.hypot((robotX - targetX), (targetY - robotY))))) - 5) < robot.getGunHeading()
            && 
            (180 + (Math.toDegrees(Math.asin((robotX - targetX) / 
                Math.hypot((robotX - targetX), (targetY - robotY))))) + 5) 
                > robot.getGunHeading()) {
          gunOnTarget = true;
        }
      }
      else {
        if ((360 - (Math.toDegrees(Math.asin((robotX - targetX) / 
            Math.hypot((robotX - targetX), (robotY - targetY))))) - 5) < robot.getGunHeading()
            && 
            (360 - (Math.toDegrees(Math.asin((robotX - targetX) / 
                Math.hypot((robotX - targetX), (robotY - targetY))))) + 5) 
                > robot.getGunHeading()) {
          gunOnTarget = true;
        }
      }
    }
  }
  
  /**
   * After the battle, check to see if gun had targeted enemy.
   *
   * @param event Details about the completed battle.
   */
  @Override
  public void onBattleCompleted(BattleCompletedEvent event) {
    assertTrue("Gun is pointing at enemy", gunOnTarget);
  }


}
